﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace ZSERP.Tools.Common
{
    /// <summary>
    /// 在线用户缓存管理
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class UserCacheManager<T>
    {
        #region 静态属性
        /// <summary>
        /// 静态用户缓存表
        /// </summary>
        public static Dictionary<long, UserEntity<T>> _UserList = new Dictionary<long, UserEntity<T>>();
        /// <summary>
        /// 过期时间
        /// </summary>
        private static int _ExpiredMinutes = 1;
        /// <summary>
        /// 定时器
        /// </summary>
        private static Timer _Timer = null;
        #endregion

        #region 静态构造函数
        /// <summary>
        /// 静态构造函数
        /// 初始化计时器
        /// </summary>
        static UserCacheManager()
        {
            _Timer = new Timer(new TimerCallback(TimerClear), null, 60000, _ExpiredMinutes * 60000);
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 清除在线用户
        /// </summary>
        /// <param name="sender"></param>
        private static void TimerClear(object sender)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncClear));
        }

        /// <summary>
        /// 异步清除过期的在线用户
        /// </summary>
        /// <param name="sender"></param>
        private static void AsyncClear(object sender)
        {
            //当前时间
            DateTime timestamp = DateTime.Now.AddMinutes(0 - _ExpiredMinutes);
            //过期的用户列表
            var expiredUserList = _UserList.Where(u => u.Value.Timestamp <= timestamp).ToList();
                //(from userEntity in _UserList where userEntity.Value.Timestamp <= timestamp select userEntity);
            if (expiredUserList.Count() > 0)
            {
                List<long> expiredUserIdentities = expiredUserList.Select(o => o.Key).ToList();
                lock (_UserList)
                {
                    foreach (long userId in expiredUserIdentities)
                        _UserList.Remove(userId);
                }
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 增加在线用户
        /// </summary>
        /// <param name="userIdentity">用户身份标识</param>
        /// <param name="userInfo">用户实体</param>
        public static void Add(long userIdentity, T userInfo)
        {
            lock (_UserList)
            {
                #region 创建用户实体
                UserEntity<T> userEntity = new UserEntity<T>
                {
                    Timestamp = DateTime.Now,
                    UserInfo = userInfo
                };
                #endregion

                if (_UserList.Keys.Contains(userIdentity))
                {
                    _UserList[userIdentity] = userEntity;
                }
                else
                {
                    _UserList.Add(userIdentity, userEntity);
                }
            }
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userIdentity"></param>
        /// <returns></returns>
        public static T Get(long userIdentity)
        {
            lock (_UserList)
            {
                if (_UserList.Keys.Contains(userIdentity))
                {
                    _UserList[userIdentity].Timestamp = DateTime.Now;
                    return _UserList[userIdentity].UserInfo;
                }
                else
                {
                    return default(T);
                }
            }
        }

        /// <summary>
        /// 移除用户缓存信息
        /// </summary>
        /// <param name="userIdentity"></param>
        public static void Remove(long userIdentity)
        {
            if (_UserList.Keys.Contains(userIdentity))
            {
                lock (_UserList)
                {
                    _UserList[userIdentity].Timestamp = DateTime.Now.AddDays(-1);
                }
            }
        }
        #endregion
    }
}
